%%@ author Grupp 3
%%@ version 1.5
%%@ copyright Grupp 3
%%@ doc The module for starting the project server for managing a single project. 

-module(projectServer).

-export([start_servers/1]).

%%@doc staring the project server and register it to ProjectId, and sends hello and projectId to server_check.
%%@spec newServer(ProjectId) -> atom
%% where
%% ProjectId = integer()  

newServer(ProjectId) ->
	ServerPid = spawn(fun()-> project_server_loop(ProjectId) end),
	register(list_to_atom(hd(io_lib:format("~w",[ProjectId]))) , ServerPid),
	{server_check, pronection_server@hamberg.it.uu.se} ! {hello, ProjectId, self()}.


%%@doc Isolation projectId in tuple list and calls newServer with it as argument.
%%@spec start_servers(List) -> atom()
%% where
%% List = [{string(), integer()}]
start_servers([]) ->
	{ok};

start_servers([H | T]) ->
	newServer(element(2, H)),
	start_servers(T).
	

%%@doc project_server_loop waiting for calls for managing tasks. If called or after 20000 milesec will loop.

project_server_loop(ProjectId) ->
	receive
	{addTask,TaskName,TaskDesc, User, ClientPid} ->
		io:format("Received a request from client ~p, to add a new task to project ~w.~n", [ClientPid, ProjectId]),
		case taskman:addTask(ProjectId, TaskName, TaskDesc, User) of
			ok -> 
				ClientPid ! {ok, self()};
			{error, Mes} -> 	
				ClientPid ! {error, Mes, self()};
			_ -> 
				io:format("error~n",[])
		end,		
		project_server_loop(ProjectId);
	{listTasks, ClientPid} ->
			io:format("Received a request from client ~p, to list all tasks in project ~w.~n", [ClientPid, ProjectId]),
				case taskman:listTasks(ProjectId) of 
					{ok, TaskLists} ->
						ClientPid ! {ok, TaskLists, self()};
					{error, Mes} ->
						ClientPid ! {error, Mes, self()};
					_ -> 
					io:format("error~n",[])
			end,
		project_server_loop(ProjectId);

	{kill, ClientPid} ->	
			{server_check, pronection_server@hamberg.it.uu.se} ! {delete, ProjectId, self()},
			io:format("Project ~w, is terminated ~n",[ProjectId]),
			erlang:raise(exit, "Boom!", []);

	{crash, ClientPid} -> 
			ClientPid ! {ok, self()},
			io:format("Project ~w, have crashed ~n",[ProjectId]),
			erlang:raise(exit, "Boom!", []);

	{check, ClientPid} ->
			ClientPid ! {ok, self()},
			project_server_loop(ProjectId);

	{taskStatusList,Status, ClientPid} ->
			io:format("Received a request from client ~p, to list task with status ~w in project ~w.~n",[ClientPid, Status, ProjectId]),
			case taskman:taskStatusList(ProjectId, Status) of
				{ok, TaskList} ->
					ClientPid ! {ok, TaskList, self()};
				{error, Mes} ->
					ClientPid ! {error, Mes, self()}
			end,
		project_server_loop(ProjectId);
	{sortTasks, Status, Order, User,ClientPid} ->
			io:format("~ntest11!~n"),
			io:format("Received a request from client ~p, to sort tasks with status ~w in project ~w.~n", [ClientPid, Status, ProjectId]),
			case taskman:sortTasks(ProjectId, Status, Order, User) of
				{ok, update} ->
					io:format("~n Update! ~n"),
					ClientPid ! {ok, update, self()};
				{ok, origin} ->
					io:format("~n Origin! ~n"),
					ClientPid ! {ok, origin, self()};
				{error, not_owner} ->
					ClientPid ! {ok, update, self()};
				{error, Mes} ->
					ClientPid ! {error, Mes, self()}
			end,
		project_server_loop(ProjectId);
	{changeTaskStatus, TaskId, NewStatus, User, ClientPid} ->
			io:format("Received a request from client ~p, to move task (~i) to ~w in project ~w.~n", [ClientPid, TaskId, NewStatus, ProjectId]),
			case taskman:changeTaskStatus(ProjectId, TaskId, NewStatus, User) of
				ok ->
					ClientPid ! {ok, self()};
				{error, Mes} ->
					ClientPid ! {error, Mes, self()}
			end,
		project_server_loop(ProjectId);
	{deleteTask, TaskId, ClientPid} ->
			io:format("Received a request from client ~p, to delete task with Id ~w in project ~w.~n",[ClientPid, TaskId, ProjectId]),
			case taskman:deleteTask(ProjectId, TaskId) of
				ok ->
					ClientPid ! {ok, self()};
				{error, Mes} ->
					ClientPid ! {error, Mes, self()}
			end,
		project_server_loop(ProjectId)
	 after 20000 ->
	    	io:format("ProjectServer ~w is still running~n",[ProjectId]),
			project_server_loop(ProjectId)
	    end.		

	
